package cn.stylefeng.guns.modular.pay.controller;

import cn.janaker.paysdk.model.result.INotifyResult;
import cn.janaker.paysdk.util.HttpServletRequestReader;
import cn.stylefeng.guns.core.module.OrderStatus;
import cn.stylefeng.guns.modular.manager.entity.*;
import cn.stylefeng.guns.modular.manager.service.*;
import cn.stylefeng.guns.modular.paytest.service.PayService;
import cn.stylefeng.guns.utils.*;
import cn.stylefeng.guns.utils.douyin.DouyinConfig;
import cn.stylefeng.guns.utils.douyin.DouyinPayCallbackContent;
import cn.stylefeng.guns.utils.douyin.PayNotifyDto;
import cn.stylefeng.guns.utils.douyin.Sign;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.util.TextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Slf4j
@Controller
@RequestMapping("/pay")
public class PayController {
    @Autowired
    private FlowPayInfoService flowPayInfoService;
    @Autowired
    private FlowOrderService flowOrderService;
    @Autowired
    private FlowZfbMemberService flowZfbMemberService;
    @Autowired
    private FlowBdMemberService flowBdMemberService;
    @Autowired
    private FlowWxMemberService flowWxMemberService;
    @Autowired
    private FlowDouyinMemberService flowDouyinMemberService;
    @Autowired
    private PayService payService;

    @ResponseBody
    @RequestMapping(value = "notifyAliPay", method = RequestMethod.POST)
    public String notifyAliPay(HttpServletRequest request){
        //String reStr = HttpServletRequestReader.ReadAsChars2(request);
        Map<String, String> params = AliUtil.convertRequestParamsToMap(request);
        //Map<String, String> params = JSON.parseObject(reStr,Map.class);
        //params.put("subject","跨市搬家");
        String paramsJson = JSON.toJSONString(params);
        System.out.println("支付宝回调：" + paramsJson);
        log.info("notifyAliPay,===============================支付宝回调：" + paramsJson);
        try {
            // 调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCertCheckV1(params, AliUtil.AliConfig.alipayCertPath,
                    AliUtil.AlipayConfig.CHARSET, AliUtil.AlipayConfig.SIGNTYPE);
            if (signVerified) {
                System.out.println("支付宝回调签名认证成功");
                // 按照支付结果异步通知中的描述，对支付结果中的业务内容进行1\2\3\4二次校验
                // 校验成功后在response中返回success，校验失败返回failure
                AlipayNotifyParam param = AliUtil.buildAlipayNotifyParam(params);
                String trade_status = param.getTradeStatus();
                // 支付成功
                if (trade_status.equals("TRADE_SUCCESS")
                        || trade_status.equals("TRADE_FINISHED")) {
                    // 处理支付成功逻辑
                    try {
                        //此处做自己的业务处理
                        //查询订单
                        QueryWrapper<FlowPayInfo> flowPayInfoQueryWrapper = new QueryWrapper<>();
                        flowPayInfoQueryWrapper.eq("pay_code",param.getOutTradeNo());
                        flowPayInfoQueryWrapper.last("limit 1");
                        FlowPayInfo flowPayInfo = flowPayInfoService.getOne(flowPayInfoQueryWrapper);
                        if(flowPayInfo != null){
                            flowPayInfo.setTradeNo(param.getTradeNo());
                            flowPayInfo.setUpdateTime(new Date());
                            flowPayInfo.setPayTime(new Date());
                            flowPayInfo.setPayStatus(OrderStatus.IsPay);
                            flowPayInfoService.updateById(flowPayInfo);
                            //更新订单
                            QueryWrapper<FlowOrder> flowOrderQueryWrapper = new QueryWrapper<>();
                            flowOrderQueryWrapper.eq("order_id",flowPayInfo.getOrderId());
                            flowOrderQueryWrapper.last("limit 1");
                            FlowOrder flowOrder = flowOrderService.getOne(flowOrderQueryWrapper);
                            if(flowOrder != null){
//                                flowOrder.setOrderStatus(OrderStatus.OrderWaitService);
//                                flowOrder.setPayStatus(OrderStatus.IsPay);
//                                flowOrder.setPayCode(param.getTradeNo());
//                                flowOrderService.updateById(flowOrder);
                                if(flowOrder.isDepositPay()==1){
                                    flowOrder.setDepositPayCode(param.getOutTradeNo());
                                    flowOrder.setDepositPay(0l);
                                    flowOrderService.updateById(flowOrder);
                                }else {
                                    flowOrder.setOrderStatus(OrderStatus.OrderWaitService);
                                    flowOrder.setPayStatus(OrderStatus.IsPay);
                                    flowOrder.setPayCode(param.getOutTradeNo());
                                    flowOrderService.updateById(flowOrder);
                                }

                                //发送支付成功短信
                                try{
                                    if(flowOrder.getZfbMemberId() != null && flowOrder.getZfbMemberId() > 0){
                                        QueryWrapper<FlowZfbMember> flowZfbMemberQueryWrapper = new QueryWrapper<>();
                                        flowZfbMemberQueryWrapper.eq("member_id",flowOrder.getZfbMemberId());
                                        flowZfbMemberQueryWrapper.last("limit 1");
                                        FlowZfbMember flowZfbMember = flowZfbMemberService.getOne(flowZfbMemberQueryWrapper);
                                        if(flowZfbMember != null){
                                            AliyuncsUtil.sendSms(2,flowZfbMember.getAccount(),"","");
                                        }
                                    }else if(flowOrder.getBdMemberId() != null && flowOrder.getBdMemberId() > 0){
                                        QueryWrapper<FlowBdMember> flowBdMemberQueryWrapper = new QueryWrapper<>();
                                        flowBdMemberQueryWrapper.eq("member_id",flowOrder.getBdMemberId());
                                        flowBdMemberQueryWrapper.last("limit 1");
                                        FlowBdMember flowBdMember = flowBdMemberService.getOne(flowBdMemberQueryWrapper);
                                        if(flowBdMember != null){
                                            AliyuncsUtil.sendSms(2,flowBdMember.getAccount(),"","");
                                        }
                                    }else if(flowOrder.getWxMemberId() != null && flowOrder.getWxMemberId() > 0){
                                        QueryWrapper<FlowWxMember> flowWxMemberQueryWrapper = new QueryWrapper<>();
                                        flowWxMemberQueryWrapper.eq("member_id",flowOrder.getWxMemberId());
                                        flowWxMemberQueryWrapper.last("limit 1");
                                        FlowWxMember flowWxMember = flowWxMemberService.getOne(flowWxMemberQueryWrapper);
                                        if(flowWxMember != null){
                                            AliyuncsUtil.sendSms(2,flowWxMember.getAccount(),"","");
                                        }
                                    }
                                }catch (Exception e){
                                    e.printStackTrace();
                                }
                            }
                        }
                    } catch (Exception e) {
                        System.out.println("支付宝回调业务处理报错,params:" + paramsJson);
                    }
                } else {
                    System.out.println("没有处理支付宝回调业务，支付宝交易状态：" + trade_status + "params:" + paramsJson);
                }
                // 如果签名验证正确，立即返回success，后续业务另起线程单独处理
                // 业务处理失败，可查看日志进行补偿，跟支付宝已经没多大关系。
                return "success";
            } else {
                System.out.println("支付宝回调签名认证失败，signVerified=false, paramsJson:" + paramsJson);
                return "failure";
            }
        } catch (AlipayApiException e) {
            System.out.println("支付宝回调签名认证失败,paramsJson:" + paramsJson + ",errorMsg:" + e.getMessage());
            e.printStackTrace();
            return "failure";
        }
    }
    @ResponseBody
    @RequestMapping(value = "notifyBdPay", method = RequestMethod.POST)
    public String notifyBdPay(HttpServletRequest request) {
        Map<String,Object> resp = new HashMap<>();
        Map<String,Object> data = new HashMap<>();
        //String reStr = HttpServletRequestReader.ReadAsChars2(request);
        Map<String, Object> params = BdUtil.convertRequestParamsToMap(request);
        //Map<String, String> params = JSON.parseObject(reStr,Map.class);
        //params.put("subject","跨市搬家");
        String paramsJson = JSON.toJSONString(params);
        System.out.println("百度支付回调：" + paramsJson);
        try{
            boolean signVerified = BdPayRSASignUtil.checkSign(params,BdUtil.BdpayConfig.publicKey);
            if(signVerified){
                if(params.get("status").toString().equals("2")){
                    //支付成功
                    QueryWrapper<FlowPayInfo> flowPayInfoQueryWrapper = new QueryWrapper<>();
                    flowPayInfoQueryWrapper.eq("pay_code",params.get("tpOrderId").toString());
                    flowPayInfoQueryWrapper.last("limit 1");
                    FlowPayInfo flowPayInfo = flowPayInfoService.getOne(flowPayInfoQueryWrapper);
                    if(flowPayInfo != null){
                        flowPayInfo.setTradeNo(params.get("orderId").toString());
                        flowPayInfo.setUserId(params.get("userId").toString());
                        flowPayInfo.setUpdateTime(new Date());
                        flowPayInfo.setPayTime(new Date());
                        flowPayInfo.setPayStatus(OrderStatus.IsPay);
                        flowPayInfoService.updateById(flowPayInfo);
                        //更新订单
                        QueryWrapper<FlowOrder> flowOrderQueryWrapper = new QueryWrapper<>();
                        flowOrderQueryWrapper.eq("order_id",flowPayInfo.getOrderId());
                        flowOrderQueryWrapper.last("limit 1");
                        FlowOrder flowOrder = flowOrderService.getOne(flowOrderQueryWrapper);
                        if(flowOrder != null){
//                            flowOrder.setOrderStatus(OrderStatus.OrderWaitService);
//                            flowOrder.setPayStatus(OrderStatus.IsPay);
//                            flowOrder.setPayCode(params.get("orderId").toString());
//                            flowOrderService.updateById(flowOrder);
//                            tpOrderId
                            if(flowOrder.isDepositPay()==1){
                                flowOrder.setDepositPayCode(params.get("tpOrderId").toString());
                                flowOrder.setDepositPay(0l);
                                flowOrderService.updateById(flowOrder);
                            }else {
                                flowOrder.setOrderStatus(OrderStatus.OrderWaitService);
                                flowOrder.setPayStatus(OrderStatus.IsPay);
                                flowOrder.setPayCode(params.get("tpOrderId").toString());
                                flowOrderService.updateById(flowOrder);
                            }
                            //发送支付成功短信
                            try{
                                if(flowOrder.getZfbMemberId() != null && flowOrder.getZfbMemberId() > 0){
                                    QueryWrapper<FlowZfbMember> flowZfbMemberQueryWrapper = new QueryWrapper<>();
                                    flowZfbMemberQueryWrapper.eq("member_id",flowOrder.getZfbMemberId());
                                    flowZfbMemberQueryWrapper.last("limit 1");
                                    FlowZfbMember flowZfbMember = flowZfbMemberService.getOne(flowZfbMemberQueryWrapper);
                                    if(flowZfbMember != null){
                                        AliyuncsUtil.sendSms(2,flowZfbMember.getAccount(),"","");
                                    }
                                }else if(flowOrder.getBdMemberId() != null && flowOrder.getBdMemberId() > 0){
                                    QueryWrapper<FlowBdMember> flowBdMemberQueryWrapper = new QueryWrapper<>();
                                    flowBdMemberQueryWrapper.eq("member_id",flowOrder.getBdMemberId());
                                    flowBdMemberQueryWrapper.last("limit 1");
                                    FlowBdMember flowBdMember = flowBdMemberService.getOne(flowBdMemberQueryWrapper);
                                    if(flowBdMember != null){
                                        AliyuncsUtil.sendSms(2,flowBdMember.getAccount(),"","");
                                    }
                                }else if(flowOrder.getWxMemberId() != null && flowOrder.getWxMemberId() > 0){
                                    QueryWrapper<FlowWxMember> flowWxMemberQueryWrapper = new QueryWrapper<>();
                                    flowWxMemberQueryWrapper.eq("member_id",flowOrder.getWxMemberId());
                                    flowWxMemberQueryWrapper.last("limit 1");
                                    FlowWxMember flowWxMember = flowWxMemberService.getOne(flowWxMemberQueryWrapper);
                                    if(flowWxMember != null){
                                        AliyuncsUtil.sendSms(2,flowWxMember.getAccount(),"","");
                                    }
                                }
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                        }
                    }
                }
                resp.put("errno",0);
                resp.put("msg","成功");
                data.put("isConsumed",2);
                data.put("isErrorOrder",0);
                resp.put("data",data);
                return JSON.toJSONString(resp);
            }else {
                System.out.println("百度回调签名认证失败，signVerified=false, paramsJson:" + paramsJson);
                resp.put("errno",1);
                resp.put("msg","百度回调签名认证失败，signVerified=false, paramsJson:" + paramsJson);
                data.put("isConsumed",2);
                data.put("isErrorOrder",1);
                resp.put("data",data);
                return JSON.toJSONString(resp);
            }
        }catch (Exception e){
            System.out.println("百度回调异常,paramsJson:" + paramsJson + ",errorMsg:" + e.getMessage());
            e.printStackTrace();
            resp.put("errno",1);
            resp.put("msg","百度回调异常,paramsJson:" + paramsJson + ",errorMsg:" + e.getMessage());
            data.put("isConsumed",2);
            data.put("isErrorOrder",1);
            resp.put("data",data);
            return JSON.toJSONString(resp);
        }
    }

    @ResponseBody
    @RequestMapping(value = "notifyWXPay", method = RequestMethod.POST)
    public String notifyWXPay(HttpServletRequest request) {
        String resStr = HttpServletRequestReader.ReadAsChars(request);
        if (resStr != null && !resStr.equals("")) {
            try {
                INotifyResult notifyResult = payService.payTypes(0, 0, resStr);
                String out_trade_no = notifyResult.outTradeNo();
                String trade_no = notifyResult.tradeNo();
                //支付成功
                QueryWrapper<FlowPayInfo> flowPayInfoQueryWrapper = new QueryWrapper<>();
                flowPayInfoQueryWrapper.eq("pay_code",out_trade_no);
                flowPayInfoQueryWrapper.last("limit 1");
                FlowPayInfo flowPayInfo = flowPayInfoService.getOne(flowPayInfoQueryWrapper);
                if(flowPayInfo != null){
                    flowPayInfo.setTradeNo(trade_no);
                    flowPayInfo.setUserId("");
                    flowPayInfo.setUpdateTime(new Date());
                    flowPayInfo.setPayTime(new Date());
                    flowPayInfo.setPayStatus(OrderStatus.IsPay);
                    flowPayInfoService.updateById(flowPayInfo);
                    //更新订单
                    QueryWrapper<FlowOrder> flowOrderQueryWrapper = new QueryWrapper<>();
                    flowOrderQueryWrapper.eq("order_id",flowPayInfo.getOrderId());
                    flowOrderQueryWrapper.last("limit 1");
                    FlowOrder flowOrder = flowOrderService.getOne(flowOrderQueryWrapper);
                    if(flowOrder != null){
                        if(flowOrder.isDepositPay()==1){
                            flowOrder.setDepositPayCode(out_trade_no);
                            flowOrder.setDepositPay(0l);
                            flowOrderService.updateById(flowOrder);
                        }else {
                            flowOrder.setOrderStatus(OrderStatus.OrderWaitService);
                            flowOrder.setPayStatus(OrderStatus.IsPay);
                            flowOrder.setPayCode(out_trade_no);
                            flowOrderService.updateById(flowOrder);
                        }

                        //发送支付成功短信
                        try{
                            if(flowOrder.getZfbMemberId() != null && flowOrder.getZfbMemberId() > 0){
                                QueryWrapper<FlowZfbMember> flowZfbMemberQueryWrapper = new QueryWrapper<>();
                                flowZfbMemberQueryWrapper.eq("member_id",flowOrder.getZfbMemberId());
                                flowZfbMemberQueryWrapper.last("limit 1");
                                FlowZfbMember flowZfbMember = flowZfbMemberService.getOne(flowZfbMemberQueryWrapper);
                                if(flowZfbMember != null){
                                    AliyuncsUtil.sendSms(2,flowZfbMember.getAccount(),"","");
                                }
                            }else if(flowOrder.getBdMemberId() != null && flowOrder.getBdMemberId() > 0){
                                QueryWrapper<FlowBdMember> flowBdMemberQueryWrapper = new QueryWrapper<>();
                                flowBdMemberQueryWrapper.eq("member_id",flowOrder.getBdMemberId());
                                flowBdMemberQueryWrapper.last("limit 1");
                                FlowBdMember flowBdMember = flowBdMemberService.getOne(flowBdMemberQueryWrapper);
                                if(flowBdMember != null){
                                    AliyuncsUtil.sendSms(2,flowBdMember.getAccount(),"","");
                                }
                            }else if(flowOrder.getWxMemberId() != null && flowOrder.getWxMemberId() > 0){
                                QueryWrapper<FlowWxMember> flowWxMemberQueryWrapper = new QueryWrapper<>();
                                flowWxMemberQueryWrapper.eq("member_id",flowOrder.getWxMemberId());
                                flowWxMemberQueryWrapper.last("limit 1");
                                FlowWxMember flowWxMember = flowWxMemberService.getOne(flowWxMemberQueryWrapper);
                                if(flowWxMember != null){
                                    AliyuncsUtil.sendSms(2,flowWxMember.getAccount(),"","");
                                }
                            }
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        return "<xml> \n" +
                "                      <return_code><![CDATA[SUCCESS]]></return_code>\n" +
                "                       <return_msg><![CDATA[OK]]></return_msg>\n" +
                "                     </xml> ";
    }




    @ResponseBody
    @RequestMapping(value = "notifyDYPay", method = RequestMethod.POST)
    public String notifyDYPay(@RequestBody PayNotifyDto dto, HttpServletRequest request) {

        log.info("notifyDYPay,dto:"+JSON.toJSONString(dto));

        String callbackToken = DouyinConfig.CALLBACK_TOKEN; // callbackToken 是平台上配置的token (callbackToken is the token configured on the platform)
        String timestamp = dto.getTimestamp();
        String nonce = dto.getNonce();
        String msg = dto.getMsg();
        List<String> sortedString = Arrays.asList(callbackToken, timestamp, nonce, msg);
        String sign = Sign.callbackSign(sortedString);
        log.info("notifyDYPay,sign:"+sign);
        if(!sign.equals(dto.getMsg_signature())){
            log.info("notifyDYPay,验签失败,sign:"+sign);
            return null;
        }

        DouyinPayCallbackContent callbackContent=JSON.parseObject(dto.getMsg(),DouyinPayCallbackContent.class);

        if (callbackContent != null && "SUCCESS".equals(callbackContent.getStatus())) {
            try {

                String out_trade_no = callbackContent.getCp_orderno();
                String trade_no = callbackContent.getOrder_id();
                //支付成功
                QueryWrapper<FlowPayInfo> flowPayInfoQueryWrapper = new QueryWrapper<>();
                flowPayInfoQueryWrapper.eq("pay_code",out_trade_no);
                flowPayInfoQueryWrapper.last("limit 1");
                FlowPayInfo flowPayInfo = flowPayInfoService.getOne(flowPayInfoQueryWrapper);
                if(flowPayInfo != null && StringUtils.isBlank(flowPayInfo.getTradeNo())){
                    flowPayInfo.setTradeNo(trade_no);
                    flowPayInfo.setUserId("");
                    flowPayInfo.setUpdateTime(new Date());
                    flowPayInfo.setPayTime(new Date());
                    flowPayInfo.setPayStatus(OrderStatus.IsPay);
                    flowPayInfoService.updateById(flowPayInfo);
                    //更新订单
                    QueryWrapper<FlowOrder> flowOrderQueryWrapper = new QueryWrapper<>();
                    flowOrderQueryWrapper.eq("order_id",flowPayInfo.getOrderId());
                    flowOrderQueryWrapper.last("limit 1");
                    FlowOrder flowOrder = flowOrderService.getOne(flowOrderQueryWrapper);
                    if(flowOrder != null){
                        if(flowOrder.isDepositPay()==1){
                            flowOrder.setDepositPayCode(out_trade_no);
                            flowOrder.setDepositPay(0l);
                            flowOrderService.updateById(flowOrder);
                        }else {
                            flowOrder.setOrderStatus(OrderStatus.OrderWaitService);
                            flowOrder.setPayStatus(OrderStatus.IsPay);
                            flowOrder.setPayCode(out_trade_no);
                            flowOrderService.updateById(flowOrder);
                        }

                        //发送支付成功短信
                        try{
                            if(flowOrder.getZfbMemberId() != null && flowOrder.getZfbMemberId() > 0){
                                QueryWrapper<FlowZfbMember> flowZfbMemberQueryWrapper = new QueryWrapper<>();
                                flowZfbMemberQueryWrapper.eq("member_id",flowOrder.getZfbMemberId());
                                flowZfbMemberQueryWrapper.last("limit 1");
                                FlowZfbMember flowZfbMember = flowZfbMemberService.getOne(flowZfbMemberQueryWrapper);
                                if(flowZfbMember != null){
                                    AliyuncsUtil.sendSms(2,flowZfbMember.getAccount(),"","");
                                }
                            }else if(flowOrder.getBdMemberId() != null && flowOrder.getBdMemberId() > 0){
                                QueryWrapper<FlowBdMember> flowBdMemberQueryWrapper = new QueryWrapper<>();
                                flowBdMemberQueryWrapper.eq("member_id",flowOrder.getBdMemberId());
                                flowBdMemberQueryWrapper.last("limit 1");
                                FlowBdMember flowBdMember = flowBdMemberService.getOne(flowBdMemberQueryWrapper);
                                if(flowBdMember != null){
                                    AliyuncsUtil.sendSms(2,flowBdMember.getAccount(),"","");
                                }
                            }else if(flowOrder.getWxMemberId() != null && flowOrder.getWxMemberId() > 0){
                                QueryWrapper<FlowWxMember> flowWxMemberQueryWrapper = new QueryWrapper<>();
                                flowWxMemberQueryWrapper.eq("member_id",flowOrder.getWxMemberId());
                                flowWxMemberQueryWrapper.last("limit 1");
                                FlowWxMember flowWxMember = flowWxMemberService.getOne(flowWxMemberQueryWrapper);
                                if(flowWxMember != null){
                                    AliyuncsUtil.sendSms(2,flowWxMember.getAccount(),"","");
                                }
                            }else if(flowOrder.getWxMemberId() != null && flowOrder.getDyMemberId() > 0){
                                QueryWrapper<FlowDouyinMember> flowDouyinMemberQueryWrapper = new QueryWrapper<>();
                                flowDouyinMemberQueryWrapper.eq("member_id",flowOrder.getDyMemberId());
                                flowDouyinMemberQueryWrapper.last("limit 1");
                                FlowDouyinMember flowDouyinMember = flowDouyinMemberService.getOne(flowDouyinMemberQueryWrapper);
                                if(flowDouyinMember != null){
                                    AliyuncsUtil.sendSms(2,flowDouyinMember.getAccount(),"","");
                                }
                            }
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }


        /**
         返回数据
         * */

        HashMap<String,Object> result=new HashMap<>();

        result.put("err_no",0);
        result.put("err_tips","success");

        return JSON.toJSONString(result);
    }
}
